package eu.webhib.webblog.gui.admin;

import eu.webhib.extgui.controller.edit.EditControllerParent;
import eu.webhib.extgui.controller.intf.EditDataProvider;
import eu.webhib.extgui.controller.intf.TreeDataProvider;
import eu.webhib.extgui.controller.tree.data.ParentTreeDataProvider;
import eu.webhib.extgui.controller.list.ListController;
import eu.webhib.extgui.controller.tree.TreeController;
import eu.webhib.extgui.controller.tree.TreeControllerListConnected;
import eu.webhib.extgui.controller.tree.ParentTreeController;
import eu.webhib.extgui.data.intf.DataItem;
import eu.webhib.extgui.data.service.intf.GuiParentChildService;
import eu.webhib.extgui.update.TreeListUpdateMngr;
import eu.webhib.frmwrk.jsf.base.EditBaseController;
import eu.webhib.webblog.domain.Category;
import eu.webhib.webblog.service.factory.ServiceFactory;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import org.apache.log4j.Logger;

/**
 * Handles the overall administration view for the category data
 */
@ManagedBean(name = "category")
@SessionScoped
public class CategoryController implements EditDataProvider<Category> {

   private static final Logger log = Logger.getLogger(CategoryController.class);
   /** Handling for the tree component */
   private TreeControllerListConnected treeController;
   /** Handling for the table list */
   private ListController listController;
   /** Handling for the editing dialog */
   private EditControllerParent<Category> editController;
   /** Handing for parent tree in edit dialog */
   ParentTreeController<Category> parentTreeController;
   /** controlling partial update requests */
   /** provide components id of tree and list component as used by view */
   /** remark: only simple definition of component does work (without any ':') */
   private static TreeListUpdateMngr treeListUpdate = new TreeListUpdateMngr("tree", "tablelist");
   /** Entity Service managing the persistent entities */
   private GuiParentChildService<Category> entityService;
   //private CategoryService entityService;

   @SuppressWarnings("CallToThreadDumpStack")
   public CategoryController() {
      log.info("CategoryController");
      entityService = ServiceFactory.getCategoryService();
      TreeDataProvider treeDataProvider = new ParentTreeDataProvider<Category>("Categories", entityService);
      listController = new ListController(treeDataProvider);
      treeController = new TreeControllerListConnected(treeDataProvider, listController, treeListUpdate);
      treeController.buildData();
      treeController.setRootSelected();
      editController = new EditControllerParent<Category>(this, entityService, treeListUpdate);
   }

   /**
    * Called by view to get tree controller for tree component
    */
   public TreeController getTree() {
      return treeController;
   }

   /**
    * Called by view to get table list controller dataTable component
    */
   public ListController getList() {
      return listController;
   }

   /**
    * Called by view to get edit controller for edit dialog
    */
   public EditControllerParent<Category> getEdit() {
      return editController;
   }

   private Category getSelectedEntity() {
      DataItem selectedItem = listController.getSelectedItem();
      log.info("getSelectedEntity: " + selectedItem);
      assert (selectedItem instanceof Category);
      return (Category) selectedItem;
   }
   //
   // EditDataProvider interface
   //

   @Override
   public Category getNewEntity() {
      log.info("getNewEntity");

      Category newEntity = entityService.createNew();
      assert (newEntity != null);
      Category selectedEntity = (Category) listController.getSelectedItem();
      if (selectedEntity != null) {
         newEntity.setParent(selectedEntity);
      }
      /** return entity to be used in edit dialog */
      return newEntity;
   }

   /**
    * Callback to retrieve entity to be edited in the edit dialog
    * @see EditDataProvider
    */
   @Override
   public Category getEntityToEdit() {
      log.info("getEntityToEdit");
      /** return entity to be used in edit dialog */
      return getSelectedEntity();
   }

   /**
    * Callback to verify new or changed entity
    * @see EditDataProvider
    */
   @Override
   public boolean verifyEntity(Category entityToCheck) {
      log.info("verifyEntity: " + entityToCheck);

      /** input field validation */
      if (entityToCheck.getTitle().isEmpty()) {
         EditBaseController.setFieldErrorFieldName("title", "error_field_input_required");
         return false;
      }
      return true;
   }

   @Override
   public void relationsChanged() {
      /** do whole tree recreation and update component in view */
      treeController.refreshData();
   }

   /**
    * Callback to delete the currently selected entity
    * @see EditDataProvider
    */
   @Override
   public Category getEntityToDelete() {
      log.info("getEntityToEdit");

      Category entityToDelete = getSelectedEntity();

      /** specific check */
      if (!entityToDelete.getChildren().isEmpty()) {
         editController.setErrorMessage("error_delete", entityToDelete.getLabel());
         return null;
      }
      return entityToDelete;
   }

   @Override
   public void performDeletion(Category entityToDelete) {
      log.info("performDeletion: " + entityToDelete);
      /** delete entity */
      entityService.delete(entityToDelete);
      /** do whole tree recreation and update component in view */
      treeController.refreshData();
   }
}
